package JUC.A1B2C3;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @className: A1B2C3ReentrantLockCondition
 * @Description:
 * @Author: wangyifei
 * @Date: 2022/9/4 17:43
 */
public class A1B2C3ReentrantLockCondition {
    public static int i = 1 ;
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition condA = lock.newCondition();
        Condition condB = lock.newCondition();
        Condition condC = lock.newCondition();

        Runnable r1 = () ->{
            while (true) {
                lock.lock();
                try {
                    while (i != 1) {
                        try {
                            condA.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("a");
                    i = 2;
                    condB.signal();
                } finally {
                    lock.unlock();
                }
//                System.out.println("r1 end");
            }
        };

        Runnable r2 = () -> {
            while(true) {
                lock.lock();
                try {
                    while (i != 2) {
                        try {
                            condB.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("b");
                    i = 3;
                    condC.signal();
                } finally {
                    lock.unlock();
                }
//                System.out.println("r2 end");
            }
        };

        Runnable r3 = () -> {
            while(true){
//                System.out.println("r3 in ");
                lock.lock();
                try {
//                    System.out.println("r3 get lock");
                    while(i != 3){
                        try {
                            condC.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("c");
                    i = 1 ;
                    condA.signal();
                }finally {
                    lock.unlock();
                }
            }
        };

        ThreadPoolExecutor pool = new ThreadPoolExecutor( 3 , 3 , 1000 , TimeUnit.SECONDS , new ArrayBlockingQueue<Runnable>(100));
        pool.execute(r1);
        pool.execute(r2);
        pool.execute(r3);
        pool.shutdown();
    }
}
